// 引入了nuxt/app模块中的UseFetchOptions类型,UseFetchOptions类型是一个用于配置请求选项的接口或类型
import type { UseFetchOptions } from 'nuxt/app'
import { useCookie, useRouter } from 'nuxt/app'
import { config } from './config'

//  HTTP 请求的方法
type Methods = 'GET' | 'POST' | 'DELETE' | 'PUT'

// URL 基地址
// eslint-disable-next-line node/prefer-global/process
const BASE_URL = process.env.NUXT_PUBLIC_API_BASE || 'https://dev-gateway.epec.com/api'

// 请求结果数据格式
export interface IResultData<T> {
  code: number
  data: T
  msg: string
  freshToken?: string // 添加可选的 freshToken 字段
  freshTokenMaxAgeToAdd?: number // 添加可选的 freshTokenMaxAgeToAdd 字段
}

/**
 * api请求封装，使用useFetch函数
 * @param {string} url 请求地址
 * @param {string} method 请求方法
 * @param {object} data 请求数据
 * @param { UseFetchOptions } options 请求选项
 */

/**
 * options常用参数说明
 * @param { boolean } lazy    是否在加载路由后才请求该异步方法，默认为false
 * @param { boolean } server  是否在服务端请求数据，默认为true
 */
class HttpRequest {
  request<T = any>(url: string, method: Methods, data: any, options?: UseFetchOptions<T>) {
    return new Promise((resolve, reject) => {
      const router = useRouter()
      // 设置请求头
      const customHeaders = {
        ...options?.headers,
        ...this.getHeader(),
      }
      console.log(customHeaders)
      // 继承UseFetchOptions类型，包含了baseURL和method两个属性
      const newOptions: UseFetchOptions<T> = {
        baseURL: BASE_URL,
        method,
        headers: customHeaders,
        ...options,
      }

      // 根据请求方法处理请求的数据
      if (method === 'GET' || method === 'DELETE') {
        // 将数据设置为newOptions的params属性
        newOptions.params = data
      }
      if (method === 'POST' || method === 'PUT') {
        // 将数据设置为newOptions的body属性
        newOptions.body = data
      }

      // 发送请求
      useFetch(url, newOptions)
        .then((res) => {
          if (res.error?.value?.statusCode === 401 || res.error?.value?.statusCode === 403) {
            // 处理 401 错误
            // console.error('未授权，重定向到登录页面')
            // eslint-disable-next-line node/prefer-global/process
            if (process.client) {
              router.push({ path: '/login', query: { redirect: location.href } }) // 跳转到登录页
            }
            reject(new Error('未授权，请重新登录'))
          }
          else {
            // 检查响应中是否包含 freshToken
            const responseData = res.data.value as IResultData<T>

            // 如果存在 freshToken，则更新 token
            if (responseData?.freshToken) {
              this.updateToken(responseData.freshToken)
              if (responseData.freshTokenMaxAgeToAdd !== undefined) {
                this.updateTokenExpiredTime(responseData.freshTokenMaxAgeToAdd)
              }
            }

            resolve(res.data.value)
          }
        })
        .catch((error) => {
          reject(error)
        })
    })
  }

  // 更新 token 的方法
  updateToken(freshToken: string) {
    // eslint-disable-next-line node/prefer-global/process
    if (!process.client)
      return

    // 更新 cookie 中的 token
    const tokenCookie = useCookie('epecToken')
    tokenCookie.value = freshToken

    console.log('Token has been refreshed')
  }

  // 更新token过期时间
  updateTokenExpiredTime(freshTokenMaxAgeToAdd: number) {
    const seconds = new Date().getTime() + freshTokenMaxAgeToAdd * 1000
    const tokenExpiredTimeCookie = useCookie('epecTokenExpiredTime')
    tokenExpiredTimeCookie.value = String(seconds)
    console.log('Token expired time has been refreshed')
  }

  getHeader() {
    // eslint-disable-next-line node/prefer-global/process
    if (!process.client)
      return {}
    let headers = {}
    // 获取 cookie

    headers = {
      'Content-Type': 'application/json',
      'epec-from': 'WEB_SITE',
      'epec-locale': 'zh',
    }
    const token = useCookie('epecToken').value || ''
    let userInfo = localStorage.getItem('userInfo')
    userInfo = JSON.parse(userInfo)
    if (token) {
      // app.store.state.epec_token = token;
      if (userInfo) {
        const companyId = userInfo.companyId
        if (companyId) {
          headers = {
            'Content-Type': 'application/json',
            'epec-sso-token': token,
            'epec-from': 'WEB_SITE',
            'epec-locale': 'zh',
            'epec-company-id': companyId,
          }
        }
        else {
          headers = {
            'Content-Type': 'application/json',
            'epec-sso-token': token,
            'epec-from': 'WEB_SITE',
            'epec-locale': 'zh',
          }
        }
      }
      else {
        headers = {
          'Content-Type': 'application/json',
          'epec-sso-token': token,
          'epec-from': 'WEB_SITE',
          'epec-locale': 'zh',
        }
      }
    }
    else {
      // localStorage.clear();
      localStorage.setItem('userInfo', null)
    }
    console.log(`当前环境: ${config.epecGrayGroup}`)
    // eslint-disable-next-line node/prefer-global/process
    if (process.env.NODE_ENV !== 'production') {
      // console.log(process.env)
      headers['epec-gray-group'] = config.epecGrayGroup
      // headers = {
      //   // 'Content-Type': 'application/json',
      //   'epec-gray-group': config.epecGrayGroup,
      //   // 'epec-sso-token': token,
      //   // 'epec-from': 'PURCHASE_WEB_SITE',
      //   // 'epec-locale': 'zh'
      // }
    }
    const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
    headers['epec-time-zone'] = timeZone
    return headers
  }

  // 封装常用方法
  get<T = any>(url: string, params?: any, options?: UseFetchOptions<T>) {
    return this.request(url, 'GET', params, options)
  }

  post<T = any>(url: string, data: any, options?: UseFetchOptions<T>) {
    return this.request(url, 'POST', data, options)
  }

  Put<T = any>(url: string, data: any, options?: UseFetchOptions<T>) {
    return this.request(url, 'PUT', data, options)
  }

  Delete<T = any>(url: string, params: any, options?: UseFetchOptions<T>) {
    return this.request(url, 'DELETE', params, options)
  }
}

const httpRequest = new HttpRequest()

export default httpRequest
